package com.kl.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.kl.domain.*;
import com.kl.em.ConstantEnum;
import com.kl.em.Result;
import com.kl.entity.TbCities;
import com.kl.entity.Transfer;
import com.kl.entity.TransferWaybill;
import com.kl.feign.CarServiceFeign;
import com.kl.feign.LineServcieFeign;
import com.kl.feign.LogisticsStoreControllerFeign;
import com.kl.feign.OrderServcieFeign;
import com.kl.mapper.TbCitiesMapper;
import com.kl.mapper.TransferMapper;
import com.kl.mapper.TransferWaybillMapper;
import com.kl.service.ITransferService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

@EnableScheduling //开启定时器
@RestController
@RequestMapping("/transferController")
public class TransferController {

    @Autowired
    private OrderServcieFeign orderServcieFeign;
    @Autowired
    private LogisticsStoreControllerFeign logisticsStoreControllerFeign;
    @Autowired
    private TransferMapper transferMapper;
    @Autowired
    private LineServcieFeign lineServcieFeign; //路线表
    @Autowired
    private CarServiceFeign carServiceFeign; //车辆表
    @Autowired
    private TransferWaybillMapper transferWaybillMapper;
    @Autowired
    private ITransferService transferService;
    @Autowired
    private TbCitiesMapper citiesMapper;
            //每天中午12点把遍历所有站点仓库，依次获取该仓库要发货的运单
    @PostMapping("/findOrderType")
    @Scheduled(cron = "0 0 12 * * ?")
    public Result findOrderType(){
        //查询所有站点 32个
        Result<List<LogisticsStoreDTO>> listResult = logisticsStoreControllerFeign.selectLogisticsStoreAll();
       if (listResult.getCode().equals(1007)){
           System.out.println("selectLogisticsStoreAll熔断");
           return Result.build(ConstantEnum.FaillBack).setResult("查询所有站点报错");
       }
        for (int ee = 0; ee < listResult.getResult().size(); ee++) {
                    //本站点id
                   // Long logisticsId = 1L;
                    Long logisticsId = listResult.getResult().get(ee).getId();
                    //获取本站点的车，状态为5  //
                Result<List<CarDTO>> bylogitIdToList = carServiceFeign.getBylogitIdToList(logisticsId);
                if (bylogitIdToList.getCode().equals(1007) || bylogitIdToList.getResult().size() <= 0){
                    System.out.println("getBylogitIdToList熔断,或者为空");
                    return Result.build(ConstantEnum.FaillBack);
                }
                //获取本站点的车的下一站站点集合，状态为5
                List<String> asd2 = new ArrayList<>();
                //获取本站点的车的id集合，状态为5
                List<CarDTO> result_cars = bylogitIdToList.getResult();
                for (CarDTO car : result_cars) {
                    System.out.println(car.getId());
                    asd2.add(car.getLineRange2());
                }
                //接下来就是一个站点内的运单管理 int q = 0; 站点.get(q).name()=本站名字(北京);
                    //下面所有操作,都是对一个站点内的操作
                    //本站点已揽收
                    if(bylogitIdToList.getCode().equals(1012)){
                        //太忙了，没车了
                        return Result.build(ConstantEnum.CAR_IS_NULL).setResult("站点无可运行车，请调度");
                    }
                    Result<List<WaybillDTO>> listResult1 = orderServcieFeign.selectByZhuang(0,logisticsId);
                    if(listResult1.getResult() == null){
                        return Result.build(ConstantEnum.ERROR).setResult("没有运单在仓库等待装车1");
                    }
                    if(listResult1.getResult().size() <= 0){
                        return Result.build(ConstantEnum.ERROR).setResult("没有运单在仓库等待装车2");
                    }
                    if (listResult1.getCode().equals(1007)){
                        System.out.println("selectByZhuang熔断");

                        return Result.build(ConstantEnum.FaillBack);
                    }
                    //本站点已揽收的所有要发货的运单
                    List<WaybillDTO> result1 = listResult1.getResult();
        //            for (WaybillDTO waybillDTO : listResult2.getResult()) {
        //                result1.add(waybillDTO);
        //            }
                    //        //获取本站点(运单)货物入库时间
                    List<Long> longs = new ArrayList<>();
                    for (WaybillDTO waybillDTO : result1) {
                        longs.add(waybillDTO.getWarehouseEntryTime().getTime());
                    }
        //        //使用入库时间排序，入库早-入库晚
                    for (int w = 0;w<longs.size(); w++){
                        for (int j = 0; j < longs.size()-1-w;j++ ){
                            if (longs.get(j + 1) < longs.get(w)){
                                Long l = longs.get(j+1);
                                longs.set(j+1,longs.get(j));
                                longs.set(j,l);
                            }
                        }
                    }
                    //按照入库时间早晚排序，该集合存储的是仓库今天要发的所有货物（运单）
                    //将本站点所有要发货的运单,重排序
                    // result3 == result1 (根据时间进行了排序)
                    List<WaybillDTO> result3 = new ArrayList<>();
                    for (WaybillDTO waybillDTO : result1) {
                        for (Long aLong : longs) {
                            long time = waybillDTO.getWarehouseEntryTime().getTime();
                            if(time==aLong){
                                result3.add(waybillDTO);
                            }
                        }
                    }
                    //该站点,要发货的所有下一站id的集合  //调接口,String是站点id字段
                    List<String> list = new ArrayList<>();
                    //本站点的每一个运单
                    for (int q = 0;q < result3.size(); q++) {
                        //当前运单所在站点 假如是北京
                        Long currentSite = result3.get(q).getCurrentSite();
                        //下一站站点
                        String nextLine_id = result3.get(q).getNextLine();
                        //将所有下一站站点id存入集合

                        list.add(nextLine_id);

                    }
                    //去重
                    // 北京: 天津 上海 郑州
                    HashSet set = new HashSet(list);
                    // 清空list集合
                    list.clear();
                    // 将去重后的元素重新添加到list中
                    // 去重完毕
                    list.addAll(set);

                    //备用 boss == boss_car （数据内容一致，中转单集合）
                    //中转单集合
                    List<List<WaybillDTO>> boss = new ArrayList<>();
                    //本站所有车集合
                    List<List<WaybillDTO>> boss_car = new ArrayList<>();
                    //下一站站点集合循环（本仓库要发货运单的下一站）
                     List<String> asd = new ArrayList<>();

                    for (String s : list) { //2  天津,石家庄 ; 2 , 3

                        //代表本站发往某一个下一站(s)的所有货物,////////////////////////该批货物装如同一两车
                        List<WaybillDTO> xia_yi_zhan = new ArrayList<>();
                        //代表本站发往某一个下一站(s)的车
                        List<WaybillDTO> xia_yi_zhan_car = new ArrayList<>();
                        //一车只能装固定吨数 50T
                        Double d = new Double(0);
                        for (int qwe = 0; qwe < result3.size(); qwe++) { // 本站两辆车所以循环2次，装2辆车：天津，石家庄 货物分几辆车装，根据目的地

                            //下一站地址
                            String nextLine = result3.get(qwe).getNextLine();
                                //b == b
                            if(s.equals(nextLine)){
                                //目的地相同的(运单)货物
                                WaybillDTO waybillDTO = result3.get(qwe);
                                //通过下一站位置,找到本站中对应车辆,
                                if(d<50.0){
                                 if(asd2.contains(s)){
                                    asd.add(s);
                                    //装车
                                    //获取下一站id，（已装车准备发往下一站的）
                                    xia_yi_zhan.add(waybillDTO);
                                    xia_yi_zhan_car.add(waybillDTO);

                                 }

                                }
                                    d += waybillDTO.getCargoWeight();

                                //Double weight = dto.getCargoWeight();
                            }
                        }
                        //boss的size就是本站点要发下一站的数量
                        boss.add(xia_yi_zhan);
                        boss_car.add(xia_yi_zhan_car);

                    }


                    //通过boss生成中转单
                    for (int i1 = 0; i1 < boss.size(); i1++) { //天津,石家庄
                        List<WaybillDTO> waybillDTOList = boss.get(i1);
                        if(waybillDTOList.size()<=0){
                            continue;//进行下一次循环、没装车，
                        }
                        Transfer transfer = new Transfer();
                        //本站点id.tostring
                        String s2 = logisticsId.toString();
                        //中转站名称
                        transfer.setTransferName(s2);
                        //中转状态
                        transfer.setTransferState(0);
                        //车辆id 通过本站的id找到车辆的id
                        // Long carId = transferMapper.selectCarIdBylogisticsId(s2);

                        // TODO 传入当前站点id，获取本站state当前状态为5的空车，没有就传null

                        if (bylogitIdToList.getCode().equals(1007)){
                            System.out.println("getBylogitIdToList熔断");

                            return Result.build(ConstantEnum.FaillBack);
                        }
                        CarDTO car = result_cars.get(i1);
                        //有车
                            //车辆id
                            transfer.setCarId(car.getId());
                            //发货地仓库
                            transfer.setSwIdSta(logisticsId);
                            //目的地仓库
                            Long nextLineId = Long.parseLong(boss.get(i1).get(0).getNextLine());
                            transfer.setSwIdEnd(nextLineId);
                            //货物类型
        //                    transfer.setTypeGoods("办公用品");
                            //TODO 员工id
                         //   Long sid = transferMapper.selectStallByCarId(car.getId());
                            transfer.setSid(car.getCarDriver());
                            //出站时间
                            transfer.setStartTime(new Date());
                            //TODO 进站时间  未完成
                            //装车完毕，通过carid修改车状态为运营中
                            //出发时间
                            car.setStartTime(new Date());
                            //2运营中
                            car.setState("2");
                            car.setCarLoad("50");
                            car.setTodayCount(car.getTodayCount()+1);
                            car.setLineRange2(boss.get(i1).get(0).getNextLine());
                            carServiceFeign.updateCar(car,car.getId(),car.getState());
                            //中转单已出车
                            transfer.setTransferState(1);
                            //执行增加方法
                            boolean insert = transfer.insert();
                            System.out.println(insert+"增加");
                            Long tid = transfer.getTid();

                            //增加中间表

                            for (int i2 = 0; i2 < boss.get(i1).size(); i2++) {

                                WaybillDTO waybillDTO = boss.get(i1).get(i2);
                                //调用order 接口 修改更新信息
                                Long currentSite = waybillDTO.getCurrentSite();
                                String nextLine1 = waybillDTO.getNextLine();
                                Long waybillId = waybillDTO.getWaybillId();
                                long l = Long.parseLong(nextLine1);
                                Result<LogisticsStoreDTO> logisticsStoreDTOResult1 = logisticsStoreControllerFeign.selectLogisticsStoreById(currentSite);
                                if (logisticsStoreDTOResult1.getCode().equals(1007)){
                                    System.out.println("storeName熔断");

                                    return Result.build(ConstantEnum.FaillBack);
                                }
                                String storeName = logisticsStoreDTOResult1.getResult().getStoreName();
                                Result<LogisticsStoreDTO> logisticsStoreDTOResult = logisticsStoreControllerFeign.selectLogisticsStoreById(l);
                                if (logisticsStoreDTOResult.getCode().equals(1007)){
                                    System.out.println("storeName1熔断");

                                    return Result.build(ConstantEnum.FaillBack);
                                }
                                String storeName1 = logisticsStoreDTOResult.getResult().getStoreName();
                                String s1 = "已离开【" + storeName + "】,下一站发往【" + storeName1 + "】";
                                //TODO 调用order 接口 修改更新信息
                                System.out.println(":运单号:"+waybillId+"--"+s1);
                                Result result = orderServcieFeign.updateUpdateInformation(waybillId, s1,"3");
                                if (result.getCode().equals(1007)){
                                    System.out.println("updateUpdateInformation熔断");
                                    return Result.build(ConstantEnum.FaillBack);
                                }

                                TransferWaybill transferWaybill = new TransferWaybill();
                                transferWaybill.setTid(tid);
                                transferWaybill.setWid(waybillId);
                                transferWaybillMapper.insert(transferWaybill);
                            }
                    }
        }

        System.out.println("-----");
        return Result.build(ConstantEnum.SUCCESS);

    }

    //获取线路表中，该站点的所有下一站   北京
    public List<String> asda(String zhandian){
        //声明变量
        List<String> xia = new ArrayList<>();
        //通过站点名，获取包含该站点的所有路线，
        List<UserDTO> list1 = new ArrayList<>();
        for (int j = 0; j < list1.size(); j++) {
            //该线路所经过的所有站点集合【北京，天津，上海】，【无锡，天津，北京】,【无锡，北京，广州】,【北京，天津，广州】
            String s = list1.get(j).getAliasName();
            List<String> strings = JSONObject.parseArray(s, String.class);
            //北京不是终点站
            if (!strings.get(strings.size() - 1).equals(zhandian)) {
                for (int i = 0; i < strings.size(); i++) {
                    boolean equals = strings.get(i).equals(zhandian);
                    if(equals){
                        //此时i等于站点在（线路所经过的所有站点集合）中的坐标
                        String s1 = strings.get(i + 1);
                        xia.add(s1);
                    }
                }
            }
        }
        // 利用list中的元素创建HashSet集合，此时set中进行了去重操作
        HashSet set = new HashSet(xia);
        // 清空list集合
        xia.clear();
         // 将去重后的元素重新添加到list中
        xia.addAll(set);
        return xia;
    }

    //下一站城市,入库时间,当前运单所在那个站点,运单id

    //中转单到站卸货
    @PostMapping("/harvest")
    public Result harvest(@RequestParam Long id){

        //通过id 查询 中转单
        Transfer transfer = transferMapper.selectById(id);
        // 发货地的 id
        Long swIdSta = transfer.getSwIdSta();
        //目的地的 id
        Long swIdEnd = transfer.getSwIdEnd();
        //通过 id 对应的运单集合

        List<Long> list = transferWaybillMapper.selectBytid(transfer.getTid());

        //修改 当前站和下一站的地址
//        WaybillDTO waybillDTO = new WaybillDTO();//??
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));

            Result<WaybillDTO> waybill = orderServcieFeign.selectById(list.get(i));
            if (waybill.getCode().equals(1007)){
                System.out.println("testById熔断");
                return Result.build(ConstantEnum.FaillBack).setResult("运单byid查询熔断");
            }
            WaybillDTO waybillDTO = waybill.getResult();

            Long lineWaybill = waybillDTO.getLineWaybill();
            //查询下一站的id
            System.out.println(waybillDTO);
            System.out.println(lineWaybill + "---" + swIdEnd);
            //下一站站点实体类.下一站id就是getId()
            Result<LineLogisticsStoreDTO> lineLogisticsStoreDTOResult = lineServcieFeign.selectNextByLineId(lineWaybill, swIdEnd);
            if (lineLogisticsStoreDTOResult.getCode().equals(1007)){
                System.out.println("selectNextByLineId熔断");
                return Result.build(ConstantEnum.FaillBack).setResult("selectNextByLineId熔断");
            }
            LineLogisticsStoreDTO result = lineLogisticsStoreDTOResult.getResult();
          //下一站的id
            if(result==null){
                //代表本站是终点站，修改运单的状态5到达终点站，
                //终点站id
                Long aLong = Long.valueOf(waybillDTO.getNextLine());
                //修改运单的当前地址
                waybillDTO.setCurrentSite(aLong);
                //终点站namne
                System.out.println("终点站id:"+aLong);
                Result<LogisticsStoreDTO> logisticsStoreDTOResult = logisticsStoreControllerFeign.selectLogisticsStoreById(aLong);
                if (logisticsStoreDTOResult.getCode().equals(1007)){
                    System.out.println("selectLogisticsStoreById熔断");
                    return Result.build(ConstantEnum.FaillBack).setResult("selectLogisticsStoreById熔断");
                }

                String storeName = logisticsStoreDTOResult.getResult().getStoreName();
                //修改 更新信息
                String s = "已到达目的地仓库【" + storeName + "】";
                //TODO set更新时间
                //TODO set更新时间
                waybillDTO.setChangeTime(new Date());
                waybillDTO.setCurrentSite(logisticsStoreDTOResult.getResult().getId());
                waybillDTO.setNextLine(logisticsStoreDTOResult.getResult().getId().toString());
                // set 入库时间
                waybillDTO.setWarehouseEntryTime(new Date());
                // set zhuangche
                waybillDTO.setZhuangche(0);
                //调用 updateUpdate 改为已到达
                Result result1 = orderServcieFeign.updateUpdateInformation(waybillDTO.getWaybillId(), s, "8");
                if (result1.getCode().equals(1007)){
                    System.out.println("修改运单状态熔断");
                    return Result.build(ConstantEnum.FaillBack).setResult("修改运单状态熔断");
                }
            }else{
                //不是到达终点站的方法
                //下一站id
                String staffWarehouseId = result.getLogisticsStoreId().toString();
                //修改运单的下一站地址
                waybillDTO.setNextLine(staffWarehouseId);
                //修改运单的当前地址
                waybillDTO.setCurrentSite(swIdEnd);
                //已签收
                waybillDTO.setLogisticsStatus("5");
                //修改 更新信息
                String s = "已到达【" + staffWarehouseId + "】";
                //调用 updateUpdate 改为已到达
                Result result1 = orderServcieFeign.updateUpdateInformation(waybillDTO.getWaybillId(), s, "3");
                if (result1.getCode().equals(1007)){
                    System.out.println("修改运单状态熔断");
                    return Result.build(ConstantEnum.FaillBack).setResult("修改运单状态熔断");
                }

            }
            //修改运单的入库时间
            waybillDTO.setWarehouseEntryTime(new Date());
            //运单更新时间
            waybillDTO.setChangeTime(new Date());
            //调用order接口 修改 运单状态
            Result result1 = orderServcieFeign.updateWaybill(waybillDTO);
            if(result1.getCode().equals(1007)){
                System.out.println("运单修改熔断");
                return Result.build(ConstantEnum.FaillBack).setResult("运单修改熔断");
            }

        }
        //更改车辆的状态
        System.out.println(transfer.getCarId());
        Result<CarDTO> carDTOResult = carServiceFeign.selectCarById(transfer.getCarId());
        if (carDTOResult.getCode().equals(1007)){
            System.out.println("selectCarById熔断");
            return Result.build(ConstantEnum.FaillBack).setResult("查询车熔断");
        }
        CarDTO car = carDTOResult.getResult();
        //车的状态
        car.setState("5");
        //车的送达时间
        car.setEbdTime(new Date());
        //通过站点id 找到对应的城市获取里程数  set 里程数
        //car.setCarMileage(lineLength.toString());
        //线路id
        //修改车的状态
        System.out.println("car:"+car);
        Result update = carServiceFeign.getBylogitIdUpdate(car);
        if(update.getCode().equals(1007)){
            System.out.println("car修改熔断");
            return Result.build(ConstantEnum.FaillBack).setResult("car修改熔断");
        }
        transfer.setTransferState(3);
        transferMapper.updateById(transfer);
        return Result.build(ConstantEnum.SUCCESS);
    }
}
